package par

import (
	"testing"

	"gitcode.com/deyiyangyang/gascheme/ast"
	"gitcode.com/deyiyangyang/gascheme/lex"
	"gitcode.com/deyiyangyang/gascheme/tok"
)

// TestQuoteParsing 测试单引号引述语法的解析
func TestQuoteParsing(t *testing.T) {
	// 测试用例列表
	testCases := []struct {
		name        string
		input       string
		expectQuote bool
	}{{
		name:        "单引号引述列表",
		input:       "'(a b c)",
		expectQuote: true,
	}, {
		name:        "单引号引述数字",
		input:       "'42",
		expectQuote: true,
	}, {
		name:        "嵌套单引号引述",
		input:       "''(a b)",
		expectQuote: true,
	}, {
		name:        "传统quote形式",
		input:       "(quote (x y z))",
		expectQuote: false, // 这是原始形式，不是通过单引号语法解析的
	}}

	// 运行每个测试用例
	for _, tc := range testCases {
		t.Run(tc.name, func(t *testing.T) {
			// 解析输入表达式
			lexer := lex.NewLexer(tc.input)
			parser := NewParser(lexer)
			expr, err := parser.ParseExpression()
			if err != nil {
				t.Fatalf("解析错误: %v", err)
			}

			// 检查结果是否为列表表达式
			listExpr, ok := expr.(*ast.ListExpression)
			if !ok {
				t.Fatalf("期望ListExpression，得到%T", expr)
			}

			// 检查第一个元素是否为quote符号
			if len(listExpr.Elements) < 1 {
				t.Fatalf("解析结果列表为空")
			}

			symbol, ok := listExpr.Elements[0].(*ast.SymbolLiteral)
			if !ok {
				t.Fatalf("列表第一个元素应该是SymbolLiteral，得到%T", listExpr.Elements[0])
			}

			if symbol.Value != "quote" {
				t.Fatalf("期望第一个元素为'quote'，得到'%s'", symbol.Value)
			}

			// 验证是否还有第二个元素（被引用的表达式）
			if len(listExpr.Elements) < 2 {
				t.Fatalf("引用表达式应该有被引用的内容")
			}

			// 如果是通过单引号语法解析的，验证token类型
			if tc.expectQuote && listExpr.Token.Type != tok.QUOTE {
				t.Fatalf("通过单引号语法解析的列表应该有QUOTE类型的token，得到%s", listExpr.Token.Type)
			}

			// 对于传统quote形式，验证token类型
			if !tc.expectQuote && listExpr.Token.Type != tok.LPAREN {
				t.Fatalf("传统quote形式的列表应该有LPAREN类型的token，得到%s", listExpr.Token.Type)
			}
		})
	}
}

// TestNestedQuoteParsing 测试嵌套的单引号引述解析
func TestNestedQuoteParsing(t *testing.T) {
	input := "''(a b)"
	lexer := lex.NewLexer(input)
	parser := NewParser(lexer)
	expr, err := parser.ParseExpression()
	if err != nil {
		t.Fatalf("解析错误: %v", err)
	}

	// 第一层应该是 (quote ...)
	outerList, ok := expr.(*ast.ListExpression)
	if !ok {
		t.Fatalf("期望外层ListExpression，得到%T", expr)
	}

	if len(outerList.Elements) < 2 || outerList.Elements[0].(*ast.SymbolLiteral).Value != "quote" {
		t.Fatalf("外层列表应该是quote形式")
	}

	// 第二层也应该是 (quote ...)
	innerExpr := outerList.Elements[1]
	innerList, ok := innerExpr.(*ast.ListExpression)
	if !ok {
		t.Fatalf("期望内层ListExpression，得到%T", innerExpr)
	}

	if len(innerList.Elements) < 2 || innerList.Elements[0].(*ast.SymbolLiteral).Value != "quote" {
		t.Fatalf("内层列表应该是quote形式")
	}

	// 最内层应该是 (a b)
	nestedExpr := innerList.Elements[1]
	nestedList, ok := nestedExpr.(*ast.ListExpression)
	if !ok {
		t.Fatalf("期望最内层ListExpression，得到%T", nestedExpr)
	}

	if len(nestedList.Elements) != 2 {
		t.Fatalf("最内层列表应该有2个元素，得到%d个", len(nestedList.Elements))
	}
}